package com.xbongbong.paas.controller.mobile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.FormDataListSearchHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.dto.ColumnSetListDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.vo.ColumnSetListVO;
import com.xbongbong.paas.service.PaasFormDataService;
import com.xbongbong.paas.service.UserConfigService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.parent.explain.HandleExplainHelp;
import com.xbongbong.pro.applist.pojo.MobileListSortPojo;
import com.xbongbong.pro.applist.pojo.dto.ListAppSearchFilterDTO;
import com.xbongbong.pro.applist.pojo.vo.MobileListSortVO;
import com.xbongbong.pro.applist.pojo.vo.SearchFilterVO;
import com.xbongbong.pro.constant.XbbProConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.formexplain.pojo.HandleExplainPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.vo.HandlerExplainVO;
import com.xbongbong.pro.product.pojo.dto.StockDateSaveFilterDTO;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderFormEntityExt;
import com.xbongbong.saas.enums.GuaranteeExplainConstant;
import com.xbongbong.saas.enums.ListGroupEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.product.ContractProductEnum;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.service.SaasListService;
import com.xbongbong.saas.service.StockDateFilterService;
import com.xbongbong.sys.enums.UserConfigEnum;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author long.rao
 * @version v1.0
 * @date 2019/3/7 15:46
 * @since v1.0
 */
@RestController
@RequestMapping(value = XbbProConstant.API_ROOT_PREFIX + "/mobile/list")
public class SearchFilterController {
    @Resource
    private SaasListService saasListService;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private UserConfigService userConfigService;
    @Resource
    private HandleExplainHelp handleExplainHelp;
    @Resource
    private PaasFormDataService paasFormDataService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private FormDataListSearchHelp formDataListSearchHelp;
    @Resource
    private StockDateFilterService stockDateFilterService;

    /**
     * 列表筛选
     * @param listAppSearchFilterDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/getSearchFilter", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getSearchFilter(@RequestBody @Valid ListAppSearchFilterDTO listAppSearchFilterDTO, BindingResult br) {
        XbbResponse<SearchFilterVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                SearchFilterVO searchFilterVo = saasListService.getSearchFilter(listAppSearchFilterDTO);
                response = new XbbResponse<>(searchFilterVo);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 列表排序
     * @param listAppSearchFilterDTO
     * @param br
     * @return
     */
    @RequestMapping(value = "/listSortItems", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String getListSortItems(@RequestBody @Valid ListAppSearchFilterDTO listAppSearchFilterDTO, BindingResult br) {
        XbbResponse<MobileListSortVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                Long formId = listAppSearchFilterDTO.getFormId();
                String corpid = listAppSearchFilterDTO.getCorpid();
                Integer businessType = listAppSearchFilterDTO.getBusinessType();
                Integer subBusinessType = listAppSearchFilterDTO.getSubBusinessType();
                HandlerExplainVO handlerExplainVO = new HandlerExplainVO();
                if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                    WorkOrderFormEntityExt formEntityExt;
                    if (Objects.equals(formId, 0L)) {
                        formEntityExt = workOrderFormModel.getDefaultAllListForm();
                    } else {
                        formEntityExt = workOrderFormModel.getByKey(formId, corpid);
                    }
                    if (formEntityExt == null) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                    }
                    WorkOrderExplainEntity workOrderExplainEntity;
                    if (Objects.equals(formId, 0L)) {
                        workOrderExplainEntity = workOrderExplainModel.getDefaultAllListExplain(corpid);
                    } else {
                        workOrderExplainEntity = workOrderExplainModel.getByFormId(formId, corpid);
                    }
                    if (workOrderExplainEntity == null) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                    }
                    List<FieldAttrEntity> explainList = JSONArray.parseArray(workOrderExplainEntity.getExplains(), FieldAttrEntity.class);
                    FormDataListDTO formDataListDTO = new FormDataListDTO();
                    BeanUtil.copyProperties(listAppSearchFilterDTO, formDataListDTO);
                    paasFormDataService.handelSaasSpecialList(explainList, formDataListDTO);
                    PaasFormEntityExt form = new PaasFormEntityExt();
                    BeanUtil.copyProperties(formEntityExt, form);
                    form.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
                    form.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                    BeanUtil.copyProperties(listAppSearchFilterDTO, handlerExplainDTO);
                    handlerExplainDTO.setExplainList(explainList);
                    handlerExplainDTO.setPaasFormEntityExt(form);
                    handlerExplainVO = handleExplainHelp.handleExplain(handlerExplainDTO);
                } else if (Objects.equals(businessType, XbbRefTypeEnum.PRODUCT.getCode()) && Objects.equals(subBusinessType, XbbRefTypeEnum.STOCK_SEARCH.getCode()) && Objects.equals(ListGroupEnum.getByCode(listAppSearchFilterDTO.getFormId().intValue()).getRefType(), XbbRefTypeEnum.GUARANTEE_SEARCH.getCode())) {
                    List<FieldAttrEntity> explainList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for (String saasAttr : GuaranteeExplainConstant.GUARANTEE_ORDER_FIELD) {
                        SelectProductEnum attrBySaasAttr = SelectProductEnum.getAttrBySaasAttr(saasAttr);
                        FieldAttrEntity fieldAttrEntity = new FieldAttrEntity();
                        BeanUtil.copyProperties(attrBySaasAttr, fieldAttrEntity);
                        fieldAttrEntity.setAttr(attrBySaasAttr.getSaasAttr());
                        if (Objects.equals(attrBySaasAttr.getSaasAttr(), SelectProductEnum.BATCH.getSaasAttr())) {
                            fieldAttrEntity.setFieldType(FieldTypeEnum.TEXT.getType());
                        }
                        explainList.add(fieldAttrEntity);
                    }
                    handlerExplainVO.setHeadList(explainList);
                    listAppSearchFilterDTO.setGroupId(formId);
                } else if (Objects.equals(XbbRefTypeEnum.WORK_REPORT.getCode(), businessType)) {
                    //表单获取
                    PaasFormEntityExt form ;
                    if (Objects.equals(formId,0L)){
                        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        param.put("corpid", "0");
                        param.put("del", 0);
                        param.put("businessType",XbbRefTypeEnum.WORK_REPORT.getCode());
                        List<PaasFormEntityExt> entitys = paasFormModel.findEntitys(param);
                        if (entitys == null || entitys.isEmpty()){
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                        }
                        form = entitys.get(0);
                    } else {
                        form = paasFormModel.getByKey(formId, corpid);
                    }
                    PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();

                    //工作报告
                    if (Objects.equals(formId, 0L) || Objects.isNull(formId)) {
                        paasFormExplainEntity = paasFormExplainModel.getWorkReportDefaultAllListExplain();
                        if (Objects.isNull(paasFormExplainEntity)) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                        }
                    } else {
                        Map<String, Object> paramMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        paramMap.put(ParameterConstant.FORMID, formId);
                        paramMap.put(ParameterConstant.CORPID, corpid);
                        paramMap.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
                        List<PaasFormExplainEntity> list = paasFormExplainModel.list(paramMap);
                        if (list == null || list.isEmpty()) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                        }
                        paasFormExplainEntity = list.get(0);
                    }
                    List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                    FormDataListDTO formDataListDTO = new FormDataListDTO();
                    BeanUtil.copyProperties(listAppSearchFilterDTO, formDataListDTO);
                    paasFormDataService.handelSaasSpecialList(explainList, formDataListDTO);
                    form.setBusinessType(XbbRefTypeEnum.WORK_REPORT.getCode());
                    form.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                    BeanUtil.copyProperties(listAppSearchFilterDTO, handlerExplainDTO);
                    handlerExplainDTO.setExplainList(explainList);
                    handlerExplainDTO.setPaasFormEntityExt(form);
                    handlerExplainVO = handleExplainHelp.handleExplain(handlerExplainDTO);

                }else if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER_V2.getCode()) && Objects.equals(formId, 0L)){
                    PaasFormExplainEntity paasFormExplainEntity= paasFormExplainModel.getSystemDefaultExplain(XbbRefTypeEnum.WORK_ORDER_V2.getCode());
                    List<FieldAttrEntity> explainList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                    FormDataListDTO formDataListDTO = new FormDataListDTO();
                    BeanUtil.copyProperties(listAppSearchFilterDTO, formDataListDTO);
                    paasFormDataService.handelSaasSpecialList(explainList, formDataListDTO);
                    PaasFormEntityExt form = new PaasFormEntityExt();

                    form.setBusinessType(XbbRefTypeEnum.WORK_ORDER_V2.getCode());
                    form.setSaasMark(SaasMarkEnum.SAAS.getCode());
                    form.setId(0L);
                    HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
                    BeanUtil.copyProperties(listAppSearchFilterDTO, handlerExplainDTO);
                    handlerExplainDTO.setExplainList(explainList);
                    handlerExplainDTO.setPaasFormEntityExt(form);
                    handlerExplainVO = handleExplainHelp.handleExplain(handlerExplainDTO);
                }
                else {
                    if (Objects.equals(businessType, XbbRefTypeEnum.PRODUCT.getCode())) {
                        PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), corpid);
                        if (paasFormEntityExt == null) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
                        }
                        if (Objects.equals(formId.intValue(), ListGroupEnum.WARNING_SEARCH.getCode()) || Objects.equals(formId.intValue(), ListGroupEnum.GUARANTEE_SEARCH.getCode())) {
                            listAppSearchFilterDTO.setGroupId(formId);
                        }
                        listAppSearchFilterDTO.setFormId(paasFormEntityExt.getId());
                    }
                    //表单获取
                    FormDataListDTO formDataListDTO = new FormDataListDTO();
                    BeanUtil.copyProperties(listAppSearchFilterDTO, formDataListDTO);
                    PaasFormEntityExt form = formDataListSearchHelp.getForm(formDataListDTO);
                    //解释获取以及处理
                    HandleExplainPojo handleExplainPojo = formDataListSearchHelp.handlExplains(formDataListDTO,form);
                    List<FieldAttrEntity> explainList = handleExplainPojo.getExplainList();
                    handlerExplainVO.setHeadList(explainList);
                }
                List<FieldAttrEntity> headList = handlerExplainVO.getHeadList();
                Iterator<FieldAttrEntity> iterator = headList.iterator();
                List<FieldAttrEntity> list = new ArrayList<>();
                // 移动端列表页可排序的字段需要与web端保持一致，逻辑是列表页的headList里的fieldType[1, 2, 3, 4, 10, 10014, 10015, 10019, 10009, 10011, 10000, 10026, 10027, 20001, 20009,20010]且editAble为1,
                while (iterator.hasNext()){
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    Integer fieldType = fieldAttrEntity.getFieldType();
                    if (Objects.equals(fieldType, FieldTypeEnum.TEXT.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.NUM.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.COMBO.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.DATETIME.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.STAR.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.ADDTIME.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.UPDATETIME.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.SERIALNO.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.USER.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.DEPT.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.RADIO_GROUP.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.ENDTIME.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.CLOSETIME.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.LINK_BUSINESS_SINGLE.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.TEXT_CHECK.getType())
                            || Objects.equals(fieldType, FieldTypeEnum.PRODUCT_STOCK.getType())){
                        list.add(fieldAttrEntity);
                    }
                }
                ColumnSetListDTO columnSetListDTO = new ColumnSetListDTO();
                BeanUtil.copyProperties(listAppSearchFilterDTO, columnSetListDTO);
                MobileListSortVO mobileListSortVO = new MobileListSortVO();
                ColumnSetListVO columnSetListVO = userConfigService.columnSetList(columnSetListDTO);
                Map<String, Object> userConfigMap = columnSetListVO.getUserConfigMap();
                MobileListSortPojo defaultField = new MobileListSortPojo();
                if (userConfigMap != null) {
                    JSONObject defaultSortField = (JSONObject) userConfigMap.getOrDefault(UserConfigEnum.DEFAULT_SORT_FIELD.getAlias(), new JSONObject());
                    if (!defaultSortField.isEmpty() && defaultSortField.get("sortAttr") != null && defaultSortField.get("sortType") != null) {
                        defaultField.setSortAttr(defaultSortField.get("sortAttr").toString());
                        defaultField.setSortType(defaultSortField.get("sortType").toString());
                    } else {
                        // 默认排序为更新时间倒序
                        defaultField.setSortAttr(FieldTypeEnum.UPDATETIME.getAlias());
                        defaultField.setSortType("desc");
                    }
                } else {
                    // 默认排序为更新时间倒序
                    defaultField.setSortAttr(FieldTypeEnum.UPDATETIME.getAlias());
                    defaultField.setSortType("desc");
                }
                mobileListSortVO.setDefaultSortField(defaultField);
                List<MobileListSortPojo> listSortItems = new ArrayList<>();
                for (FieldAttrEntity entity: list) {
                    if(Objects.equals(entity.getDisableListSort(),1)){
                        continue;
                    }
                    MobileListSortPojo mobileListSortPojo = new MobileListSortPojo();
                    mobileListSortPojo.setSortAttr(entity.getAttr());
                    mobileListSortPojo.setSortAttrName(entity.getAttrName());
                    listSortItems.add(mobileListSortPojo);
                }
                if (listSortItems.isEmpty()) {
                    MobileListSortPojo mobileListSortPojo = new MobileListSortPojo();
                    mobileListSortPojo.setSortAttr(FieldTypeEnum.UPDATETIME.getAlias());
                    mobileListSortPojo.setSortAttrName(FieldTypeEnum.UPDATETIME.getDescription());
                    listSortItems.add(mobileListSortPojo);
                }
                if (Objects.equals(listAppSearchFilterDTO.getSubBusinessType(), XbbRefTypeEnum.WAIT_INSTOCK_PURCHASE.getCode()) && Objects.equals(listAppSearchFilterDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())){
                    MobileListSortPojo mobileListSortPojo = new MobileListSortPojo();
                    mobileListSortPojo.setSortAttr(ProductEnum.STOCK.getAttr());
                    mobileListSortPojo.setSortAttrName("待入库数量");
                    listSortItems.add(mobileListSortPojo);
                }
                if (Objects.equals(listAppSearchFilterDTO.getSubBusinessType(), XbbRefTypeEnum.WAIT_PURCHASE.getCode()) && Objects.equals(listAppSearchFilterDTO.getBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())){
                    MobileListSortPojo mobileListSortPojo = new MobileListSortPojo();
                    mobileListSortPojo.setSortAttr(ContractProductEnum.NUM.getAttr());
                    mobileListSortPojo.setSortAttrName("销售数量");
                    listSortItems.add(mobileListSortPojo);
                    MobileListSortPojo mobileListSortUnitPojo = new MobileListSortPojo();
                    mobileListSortUnitPojo.setSortAttr(ContractProductEnum.UNIT.getAttr());
                    mobileListSortUnitPojo.setSortAttrName("销售单位");
                    listSortItems.add(mobileListSortUnitPojo);

                }
                mobileListSortVO.setListSortItems(listSortItems);
                if (Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(),businessType) && Objects.equals(XbbRefTypeEnum.WAIT_PURCHASE.getCode(),subBusinessType)){
                    mobileListSortVO.setDefaultSortField(new MobileListSortPojo());
                    mobileListSortVO.setListSortItems(new ArrayList<>());
                }
                response = new XbbResponse<>(mobileListSortVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response, SerializerFeature.DisableCircularReferenceDetect);
    }

    @RequestMapping(value = "/saveFilter", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String saveFilter(@RequestBody @Valid StockDateSaveFilterDTO saveFilterDTO, BindingResult br) {
        XbbResponse<BaseVO> response;
        if (br.hasErrors()) {
            String errMsg = Objects.requireNonNull(br.getFieldError()).getDefaultMessage();
            response = new XbbResponse<>(SystemErrorCodeEnum.API_ERROR_100002, errMsg);
        } else {
            try {
                BaseVO baseVO = stockDateFilterService.saveStockDateFilter(saveFilterDTO);
                response = new XbbResponse<>(baseVO);
            } catch (XbbException e) {
                response = new XbbResponse<>(e);
            }
        }
        return JSON.toJSONString(response);
    }

}
